package com.haha.keymap;


import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


public class SkillConfiguratorApp extends JFrame {

    // 用于捕获全局按键事件
    private static final int F11_KEYCODE = 122;
    // UI状态常量
    private static final String RECORD_POSITION = "记录位置";
    private static final String RECORD_COLOR = "记录颜色";
    private static final String CONFIG_KEY = "配置按键";
    private CardLayout cardLayout;
    private JPanel cardsPanel;
    private List<SkillConfig> skillConfigs = new ArrayList<>();
    private SkillConfig currentSkill;
    private Robot robot;
    private JSONObject configData = new JSONObject();
    private KeyboardHook keyboardHook;

    public SkillConfiguratorApp() {
        try {
            robot = new Robot();
        } catch (AWTException e) {
            JOptionPane.showMessageDialog(this, "无法创建机器人对象: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            System.exit(1);
        }

        setupUI();
        setupKeyboardHook();

        setTitle("游戏技能助手配置工具");
        setSize(600, 400);
        setMinimumSize(new Dimension(500, 350));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            SkillConfiguratorApp app = new SkillConfiguratorApp();
            app.setVisible(true);
        });
    }

    private void setupKeyboardHook() {
        keyboardHook = new KeyboardHook();
        keyboardHook.addKeyListener(new KeyboardListener() {
            @Override
            public void onKeyPressed(int keyCode) {
                if (keyCode == F11_KEYCODE) {
                    handleF11Pressed();
                }
            }
        });
        keyboardHook.start();
    }

    private void handleF11Pressed() {
        String currentState = (String) cardsPanel.getClientProperty("current_state");

        if (RECORD_POSITION.equals(currentState)) {
            recordPosition();
        } else if (RECORD_COLOR.equals(currentState)) {
            recordColor();
        }
    }

    private void setupUI() {
        cardLayout = new CardLayout();
        cardsPanel = new JPanel(cardLayout);
        cardsPanel.putClientProperty("current_state", RECORD_POSITION);

        // 第1步：记录位置
        JPanel positionPanel = createPositionPanel();
        cardsPanel.add(positionPanel, RECORD_POSITION);

        // 第2步：记录颜色
        JPanel colorPanel = createColorPanel();
        cardsPanel.add(colorPanel, RECORD_COLOR);

        // 第3步：配置按键
        JPanel keyPanel = createKeyPanel();
        cardsPanel.add(keyPanel, CONFIG_KEY);

        add(cardsPanel, BorderLayout.CENTER);

        // 导航按钮面板
        JPanel navPanel = new JPanel();
        navPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

        JButton backButton = new JButton("上一步");
        backButton.addActionListener(e -> navigateBack());

        JButton nextButton = new JButton("下一步");
        nextButton.addActionListener(e -> navigateNext());

        JButton finishButton = new JButton("完成");
        finishButton.addActionListener(e -> finishConfiguration());

        JButton saveButton = new JButton("保存到文件");
        saveButton.addActionListener(e -> saveToJson());

        navPanel.add(backButton);
        navPanel.add(nextButton);
        navPanel.add(finishButton);
        navPanel.add(saveButton);

        add(navPanel, BorderLayout.SOUTH);
    }

    private JPanel createPositionPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

        JLabel titleLabel = new JLabel("记录技能位置", SwingConstants.CENTER);
        titleLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 18));
        panel.add(titleLabel, BorderLayout.NORTH);

        JTextArea instructionArea = new JTextArea();
        instructionArea.setText("\n步骤说明:\n" +
                "1. 请将鼠标移动到游戏中的技能区域\n" +
                "2. 按F11键记录当前位置\n" +
                "3. 您需要为每个技能记录两个位置点\n" +
                "4. 点击'下一步'继续配置颜色");
        instructionArea.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));
        instructionArea.setEditable(false);
        instructionArea.setOpaque(false);

        JPanel centerPanel = new JPanel(new BorderLayout());
        centerPanel.add(instructionArea, BorderLayout.CENTER);

        // 技能列表
        DefaultListModel<SkillConfig> listModel = new DefaultListModel<>();
        for (SkillConfig skill : skillConfigs) {
            listModel.addElement(skill);
        }
        JList<SkillConfig> skillList = new JList<>(listModel);
        skillList.setCellRenderer(new SkillListRenderer());
        JScrollPane scrollPane = new JScrollPane(skillList);
        scrollPane.setPreferredSize(new Dimension(300, 150));

        centerPanel.add(scrollPane, BorderLayout.SOUTH);
        panel.add(centerPanel, BorderLayout.CENTER);

        JButton manualRecordButton = new JButton("手动记录位置");
        manualRecordButton.addActionListener(e -> recordPosition());
        panel.add(manualRecordButton, BorderLayout.SOUTH);

        return panel;
    }

    private JPanel createColorPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

        JLabel titleLabel = new JLabel("记录技能颜色", SwingConstants.CENTER);
        titleLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 18));
        panel.add(titleLabel, BorderLayout.NORTH);

        JPanel centerPanel = new JPanel(new GridLayout(2, 1, 10, 10));

        // 第一个点颜色区域
        JPanel point1Panel = new JPanel();
        point1Panel.setBorder(BorderFactory.createTitledBorder("位置点1"));
        point1Panel.setLayout(new BoxLayout(point1Panel, BoxLayout.Y_AXIS));

        JLabel point1PosLabel = new JLabel("坐标: 未记录");
        point1PosLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));

        JPanel point1ColorPanel = new JPanel();
        point1ColorPanel.setPreferredSize(new Dimension(50, 50));
        point1ColorPanel.setBackground(new Color(240, 240, 240));
        point1ColorPanel.setBorder(BorderFactory.createLineBorder(Color.GRAY));

        JButton recordPoint1Button = new JButton("记录颜色 (F11)");
        recordPoint1Button.addActionListener(e -> currentSkill.setCurrentPoint(1));

        point1Panel.add(point1PosLabel);
        point1Panel.add(Box.createVerticalStrut(10));
        point1Panel.add(point1ColorPanel);
        point1Panel.add(Box.createVerticalStrut(10));
        point1Panel.add(recordPoint1Button);

        // 第二个点颜色区域
        JPanel point2Panel = new JPanel();
        point2Panel.setBorder(BorderFactory.createTitledBorder("位置点2"));
        point2Panel.setLayout(new BoxLayout(point2Panel, BoxLayout.Y_AXIS));

        JLabel point2PosLabel = new JLabel("坐标: 未记录");
        point2PosLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));

        JPanel point2ColorPanel = new JPanel();
        point2ColorPanel.setPreferredSize(new Dimension(50, 50));
        point2ColorPanel.setBackground(new Color(240, 240, 240));
        point2ColorPanel.setBorder(BorderFactory.createLineBorder(Color.GRAY));

        JButton recordPoint2Button = new JButton("记录颜色 (F11)");
        recordPoint2Button.addActionListener(e -> currentSkill.setCurrentPoint(2));

        point2Panel.add(point2PosLabel);
        point2Panel.add(Box.createVerticalStrut(10));
        point2Panel.add(point2ColorPanel);
        point2Panel.add(Box.createVerticalStrut(10));
        point2Panel.add(recordPoint2Button);

        // 存储组件引用
        currentSkill = new SkillConfig();
        currentSkill.setPoint1PosLabel(point1PosLabel);
        currentSkill.setPoint1ColorPanel(point1ColorPanel);
        currentSkill.setPoint2PosLabel(point2PosLabel);
        currentSkill.setPoint2ColorPanel(point2ColorPanel);

        centerPanel.add(point1Panel);
        centerPanel.add(point2Panel);

        panel.add(centerPanel, BorderLayout.CENTER);

        JLabel instructionLabel = new JLabel("请将鼠标移动到记录的位置点上，按F11键记录颜色");
        instructionLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));
        instructionLabel.setHorizontalAlignment(SwingConstants.CENTER);
        panel.add(instructionLabel, BorderLayout.SOUTH);

        return panel;
    }

    private JPanel createKeyPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

        JLabel titleLabel = new JLabel("配置按键", SwingConstants.CENTER);
        titleLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 18));
        panel.add(titleLabel, BorderLayout.NORTH);

        JPanel centerPanel = new JPanel();
        centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.Y_AXIS));

        JLabel skillNameLabel = new JLabel("技能名称: ");
        skillNameLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));

        JTextField skillNameField = new JTextField(20);
        skillNameField.setMaximumSize(new Dimension(300, 30));

        JLabel keyLabel = new JLabel("按键绑定: ");
        keyLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));

        JComboBox<String> keyCombo = new JComboBox<>();
        for (char c = 'A'; c <= 'Z'; c++) {
            keyCombo.addItem(String.valueOf(c));
        }
        keyCombo.setMaximumSize(new Dimension(100, 30));

        JButton saveSkillButton = new JButton("保存技能配置");

        centerPanel.add(Box.createVerticalStrut(20));
        centerPanel.add(skillNameLabel);
        centerPanel.add(Box.createVerticalStrut(5));
        centerPanel.add(skillNameField);
        centerPanel.add(Box.createVerticalStrut(15));
        centerPanel.add(keyLabel);
        centerPanel.add(Box.createVerticalStrut(5));
        centerPanel.add(keyCombo);
        centerPanel.add(Box.createVerticalStrut(20));
        centerPanel.add(saveSkillButton);

        panel.add(centerPanel, BorderLayout.CENTER);

        // 保存技能按钮动作
        saveSkillButton.addActionListener(e -> {
            String skillName = skillNameField.getText();
            if (skillName.isEmpty()) {
                JOptionPane.showMessageDialog(this, "请输入技能名称", "输入错误", JOptionPane.WARNING_MESSAGE);
                return;
            }

            String keyBinding = (String) keyCombo.getSelectedItem();
            currentSkill.setSkillName(skillName);
            currentSkill.setKeyBinding(keyBinding);
            skillConfigs.add(currentSkill);

            // 保存到配置数据
            saveToConfigData(currentSkill);

            // 重置当前技能
            currentSkill = new SkillConfig();

            // 提示并返回到位置记录页面
            JOptionPane.showMessageDialog(this,
                    "技能配置已保存!\n名称: " + skillName + "\n按键: " + keyBinding,
                    "保存成功",
                    JOptionPane.INFORMATION_MESSAGE);

            cardLayout.show(cardsPanel, RECORD_POSITION);
            cardsPanel.putClientProperty("current_state", RECORD_POSITION);
        });

        return panel;
    }

    private void recordPosition() {
        Point mousePoint = MouseInfo.getPointerInfo().getLocation();

        if (currentSkill == null) {
            currentSkill = new SkillConfig();
        }

        // 记录位置
        if (currentSkill.getPoint1() == null) {
            currentSkill.setPoint1(mousePoint);
        } else if (currentSkill.getPoint2() == null) {
            currentSkill.setPoint2(mousePoint);
            // 两个点都记录完成后自动进入下一步
            SwingUtilities.invokeLater(() -> {
                cardLayout.show(cardsPanel, RECORD_COLOR);
                cardsPanel.putClientProperty("current_state", RECORD_COLOR);
            });
        } else {
            // 为下一个技能创建新配置
            skillConfigs.add(currentSkill);
            currentSkill = new SkillConfig();
            currentSkill.setPoint1(mousePoint);
        }

        repaint();
    }

    private void recordColor() {
        if (currentSkill == null || currentSkill.getCurrentPoint() == 0) {
            JOptionPane.showMessageDialog(this, "请先选择要记录哪个位置点", "提示", JOptionPane.INFORMATION_MESSAGE);
            return;
        }

        Point mousePoint = MouseInfo.getPointerInfo().getLocation();
        Color color = robot.getPixelColor(mousePoint.x, mousePoint.y);

        if (currentSkill.getCurrentPoint() == 1) {
            currentSkill.setColor1(color);
            currentSkill.getPoint1ColorPanel().setBackground(color);
            currentSkill.getPoint1PosLabel().setText(String.format("坐标: (%d, %d)", mousePoint.x, mousePoint.y));
        } else {
            currentSkill.setColor2(color);
            currentSkill.getPoint2ColorPanel().setBackground(color);
            currentSkill.getPoint2PosLabel().setText(String.format("坐标: (%d, %d)", mousePoint.x, mousePoint.y));
        }

        // 自动进入下一步
        if (currentSkill.getColor1() != null && currentSkill.getColor2() != null) {
            SwingUtilities.invokeLater(() -> {
                cardLayout.show(cardsPanel, CONFIG_KEY);
                cardsPanel.putClientProperty("current_state", CONFIG_KEY);
            });
        }
    }

    private void navigateBack() {
        String currentState = (String) cardsPanel.getClientProperty("current_state");

        if (RECORD_COLOR.equals(currentState)) {
            cardLayout.show(cardsPanel, RECORD_POSITION);
            cardsPanel.putClientProperty("current_state", RECORD_POSITION);
        } else if (CONFIG_KEY.equals(currentState)) {
            cardLayout.show(cardsPanel, RECORD_COLOR);
            cardsPanel.putClientProperty("current_state", RECORD_COLOR);
        }
    }

    private void navigateNext() {
        String currentState = (String) cardsPanel.getClientProperty("current_state");

        if (RECORD_POSITION.equals(currentState)) {
            if (currentSkill.getPoint1() == null || currentSkill.getPoint2() == null) {
                JOptionPane.showMessageDialog(this, "请先记录两个位置点", "提示", JOptionPane.INFORMATION_MESSAGE);
                return;
            }
            cardLayout.show(cardsPanel, RECORD_COLOR);
            cardsPanel.putClientProperty("current_state", RECORD_COLOR);
        } else if (RECORD_COLOR.equals(currentState)) {
            if (currentSkill.getColor1() == null || currentSkill.getColor2() == null) {
                JOptionPane.showMessageDialog(this, "请先记录两个位置点的颜色", "提示", JOptionPane.INFORMATION_MESSAGE);
                return;
            }
            cardLayout.show(cardsPanel, CONFIG_KEY);
            cardsPanel.putClientProperty("current_state", CONFIG_KEY);
        }
    }

    private void finishConfiguration() {
        int response = JOptionPane.showConfirmDialog(
                this,
                "是否保存配置并退出?",
                "完成配置",
                JOptionPane.YES_NO_OPTION,
                JOptionPane.QUESTION_MESSAGE);

        if (response == JOptionPane.YES_OPTION) {
            saveToJson();
            System.exit(0);
        }
    }

    private void saveToJson() {
        if (skillConfigs.isEmpty()) {
            JOptionPane.showMessageDialog(this, "没有配置可以保存", "提示", JOptionPane.WARNING_MESSAGE);
            return;
        }

        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setDialogTitle("保存配置");
        fileChooser.setFileFilter(new javax.swing.filechooser.FileNameExtensionFilter("JSON文件 (*.json)", "json"));

        int userSelection = fileChooser.showSaveDialog(this);

        if (userSelection == JFileChooser.APPROVE_OPTION) {
            File fileToSave = fileChooser.getSelectedFile();
            if (!fileToSave.getName().toLowerCase().endsWith(".json")) {
                fileToSave = new File(fileToSave.getAbsolutePath() + ".json");
            }

            // 创建JSON数组保存所有技能配置
            JSONArray skillsArray = new JSONArray();

            for (SkillConfig skill : skillConfigs) {
                JSONObject skillObj = new JSONObject();

                // 位置1
                JSONObject pos1 = new JSONObject();
                pos1.put("x", skill.getPoint1().x);
                pos1.put("y", skill.getPoint1().y);
                skillObj.put("position1", pos1);

                // 颜色1
                JSONObject color1 = new JSONObject();
                color1.put("r", skill.getColor1().getRed());
                color1.put("g", skill.getColor1().getGreen());
                color1.put("b", skill.getColor1().getBlue());
                skillObj.put("color1", color1);

                // 位置2
                JSONObject pos2 = new JSONObject();
                pos2.put("x", skill.getPoint2().x);
                pos2.put("y", skill.getPoint2().y);
                skillObj.put("position2", pos2);

                // 颜色2
                JSONObject color2 = new JSONObject();
                color2.put("r", skill.getColor2().getRed());
                color2.put("g", skill.getColor2().getGreen());
                color2.put("b", skill.getColor2().getBlue());
                skillObj.put("color2", color2);

                // 其他信息
                skillObj.put("skill_name", skill.getSkillName());
                skillObj.put("key_binding", skill.getKeyBinding());

                skillsArray.add(skillObj);
            }

            configData.put("skills", skillsArray);

            try (FileWriter file = new FileWriter(fileToSave)) {
                file.write(configData.toJSONString());
                file.flush();

                JOptionPane.showMessageDialog(
                        this,
                        "配置已成功保存到: " + fileToSave.getAbsolutePath(),
                        "保存成功",
                        JOptionPane.INFORMATION_MESSAGE);
            } catch (IOException e) {
                JOptionPane.showMessageDialog(
                        this,
                        "保存文件时出错: " + e.getMessage(),
                        "错误",
                        JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    private void saveToConfigData(SkillConfig skill) {
        if (configData.get("skills") == null) {
            configData.put("skills", new JSONArray());
        }

        JSONArray skillsArray = (JSONArray) configData.get("skills");

        JSONObject skillObj = new JSONObject();
        JSONObject pos1 = new JSONObject();
        pos1.put("x", skill.getPoint1().x);
        pos1.put("y", skill.getPoint1().y);

        JSONObject color1 = new JSONObject();
        color1.put("r", skill.getColor1().getRed());
        color1.put("g", skill.getColor1().getGreen());
        color1.put("b", skill.getColor1().getBlue());

        JSONObject pos2 = new JSONObject();
        pos2.put("x", skill.getPoint2().x);
        pos2.put("y", skill.getPoint2().y);

        JSONObject color2 = new JSONObject();
        color2.put("r", skill.getColor2().getRed());
        color2.put("g", skill.getColor2().getGreen());
        color2.put("b", skill.getColor2().getBlue());

        skillObj.put("position1", pos1);
        skillObj.put("color1", color1);
        skillObj.put("position2", pos2);
        skillObj.put("color2", color2);
        skillObj.put("skill_name", skill.getSkillName());
        skillObj.put("key_binding", skill.getKeyBinding());

        skillsArray.add(skillObj);
    }


}




